#ifndef FUKCJE_H
#define FUKCJE_H

#endif // FUKCJE_H



#include <iostream>
#include <fstream>
#include <bitset>
#include <string>
//#include <ctime>
//#include<conio.h>
#include <sstream>


using namespace std;

//macierz generujaca kodu
short tabH[8][16]=  {
    {0,1,0,0,1,0,1,1,1,0,0,0,0,0,0,0},
    {1,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0},
    {1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0},
    {0,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0},
    {1,0,1,1,0,0,1,0,0,0,0,0,1,0,0,0},
    {0,1,0,1,1,0,0,1,0,0,0,0,0,1,0,0},
    {1,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0},
    {0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1}

};




string intToStr(int n)
{
     string tmp, ret;
     if(n < 0) {
          ret = "-";
          n = -n;
     }
     do {
          tmp += n % 10 + 48;
          n -= n % 10;
     }
     while(n /= 10);
     for(int i = tmp.size(); i >= 0; i--)
          ret += tmp[i];
     return ret;
}





int ile_bledow(int wej[16])
{

    int pom[8]={0,0,0,0,0,0,0,0};

    for(int i=0; i<8; i++)
      for(int j=0; j<16; j++)
        {pom[i]= (pom[i]+( tabH[i][j]*wej[j] ))  ;
           pom[i]=pom[i]%2;
        }
        //wektor bledu ?

    bool poprawny=true;
    for(int i=0; i<8; i++)
      if(pom[i]==1)
      {
          poprawny=false;
          break;
      }

    if (poprawny==false){
      {
         int ile=0;
         for(int i=0; i<16; i++)
         {
           ile=0;
           for(int j=0; j<8; j++)
           {
           if(pom[j]==tabH[j][i])
           ile++;
           }
           if (ile==8)
            return 1;
         }
      }

      {
         int ile=0;
         int suma[8];
         for(int i=0; i<16; i++){
           for(int j=i+1; j<16; j++){
             ile=0;
             for(int k=0; k<8; k++)
               suma[k]=(tabH[k][i]+tabH[k][j]) % 2;
             for(int k=0; k<8; k++)
             {
               if(pom[k]==suma[k])
                 ile++;
             }
             if (ile==8)
               return 2;
           }
         }
       }
       return 3;
    }
    else return 0;
}



void konwertujNaTab(char znak, int kod[8]){
    bitset<8> pom=znak;

    for(int i=0; i<8; i++)
      {
      kod[i]=pom[7-i];
      cout<<" B["<<i<<"] = "<<kod[i];

  }
  cout<<"\n";
}




char zamienTabliceNaChar(int a[8]){
    char wynik=0;
    for(int i=0; i<8; i++){
        int mnoznik=1;
        if(a[i]==1){
            for(int j=0; j<7-i; j++)
              mnoznik*=2;
        }
        else
          mnoznik=0;
        wynik+=mnoznik;
    }
    return wynik;
}




void konwertuj(int wej_ASCII[8], int wyj_bin[16])
{
    for(int i=0; i<8; i++)
      wyj_bin[i]=wej_ASCII[i];

    for(int i=8; i<16; i++)
    {
        int par=0;
                for(int k=0; k<8; k++)
                {
                par=( par+(tabH[i-8][k]*wej_ASCII[k]) );
                par = par%2;
                }
        wyj_bin[i]=par;
    }
}






//w pom przechowujemy zakodowany znak w ASCII

string zakoduj(string dane_wejsciowe)
{

    int pom[8], tab_binary[16];
    ostringstream ss;


    for (unsigned int i = 0; i<dane_wejsciowe.size(); i++){

        konwertujNaTab(dane_wejsciowe[i],pom);
        konwertuj(pom,tab_binary);

        for(int i=0; i<16; i++)
          {

            ss<<tab_binary[i];
        }
       // ss<<"\n";

    }

return ss.str();
}



void pojedynczy_blad(int tab_binary[16]){
    int pom[8]={0,0,0,0,0,0,0,0};
    for(int i=0; i<8; i++)
      for(int j=0; j<16; j++)
        pom[i]=( pom[i]+( tabH[i][j]*tab_binary[j] ) ) % 2;
    int ile=0;
    for(int i=0; i<16; i++){
        ile=0;
        for(int j=0; j<8; j++){
            if(pom[j]==tabH[j][i])
              ile++;
        }
        if (ile==8){

          if (tab_binary[i]==0) tab_binary[i]=1;
          else tab_binary[i]=0;
        }
    }
}




void podwojny_blad(int tab_binary[16]){
    int pom[8]={0,0,0,0,0,0,0,0};
    int sumtab_binary[7];
    for(int i=0; i<8; i++)
      for(int j=0; j<16; j++){
        pom[i]=( pom[i]+( tabH[i][j]*tab_binary[j] ) ) % 2;
      }

    int ile=0;
    for(int i=0; i<16; i++){
        for(int j=i+1; j<16; j++){
          ile=0;
          for(int k=0; k<8; k++)
            sumtab_binary[k]=(tabH[k][i]+tabH[k][j]) % 2;
          for(int k=0; k<8; k++){
            if(pom[k]==sumtab_binary[k])
              ile++;
          }
          if (ile==8){

            if (tab_binary[i]==0) tab_binary[i]=1;
              else tab_binary[i]=0;
            if (tab_binary[j]==0) tab_binary[j]=1;
              else tab_binary[j]=0;
          }
        }
    }
}




void  dekoduj_znak(int a[16], int b[8]){
    int wynik=ile_bledow(a);
    switch(wynik){
        case 0:
            cout<<" brak bledu w znaku "<<endl;
            break;

        case 1:
            cout<<" wykryto pojedynczy blad! "<<endl;
            pojedynczy_blad(a);
                break;
        case 2:
            cout<<" wykryto podwojny blad! "<<endl;
            podwojny_blad(a);
                break;
    }

    for(int i=0; i<8; i++)
        b[i]=a[i];

}



string dekoduj(string zakodowane_wejscie){

    int tab_bin[16];
    char tmp;
    for (int i=0; i<16; i++)
    {

       tmp= zakodowane_wejscie[i];
       char tmp;
       for (int i=0; i<16; i++)
       {

          tmp= zakodowane_wejscie[i];
           if (tmp==49)

           tab_bin[i]=1;


     }


    return "asd";
  }



}


//    /*

//    int tab_binary[16], wyjscie[8];
//    char ch;

//    int i=0;
//    while(plik_wej.eof()==0)
//    {
//        for(i=0; i<16; i++){
//          plik_wej.get(ch);
//          if(ch=='\n')
//            plik_wej.get(ch);
//          if (plik_wej.eof()==1)
//            break;
//          if (ch=='1')
//            tab_binary[i]=1;
//          else if(ch=='0')
//            tab_binary[i]=0;

//        }
//        if (plik_wej.eof()==0)
//        {

//          dekoduj_znak(tab_binary, wyjscie);
//          char a=zamienTabliceNaChar(wyjscie);


//          plik_wyj.put(a);
//        }
//    }
//    */
